#include "../inc/rpcGloableTables.h"
#include "../inc/rpc_client.h"
#include "../inc/socket_list.h"

SOCKET_LIST_NODE socketList[SOCKET_LIST_NUM];
int RpcSocketCreate()
{
	int list,i;
	struct sockaddr_in serv_addr;
	
	for(list =0;list <SOCKET_LIST_NUM;list++)
	{
		for (i = 0; i < MAX_CC_NUM; i++)
		{
			if (g_cc_ipaddr_list[i][0] == 0)
				continue;
			while(1)
			{
				socketList[list].rpc_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
				if (socketList[list].rpc_fd[i] < 0)
				{
					return -1;
				}
				
				memset(&serv_addr, 0, sizeof(struct sockaddr_in));
				serv_addr.sin_family = AF_INET;
				serv_addr.sin_port = htons(RPC_SERV_PORT);
				serv_addr.sin_addr.s_addr = inet_addr(g_cc_ipaddr_list[i]);

				if(0 != connect(socketList[list].rpc_fd[i], (struct sockaddr*)&serv_addr, sizeof(struct sockaddr)))
				{
					close(socketList[list].rpc_fd[i]);
					socketList[list].rpc_fd[i] = 0;
					taskDelay(100);
				}
				else
				{
					break ;
				}
			}
		}
		socketListIn(list);
	}
	return 0;
}

int RpcSocketReCreate(void)
{
	int list,i;
	struct sockaddr_in serv_addr;

	if(init_flag)
	{
		for(list =0;list <SOCKET_LIST_NUM;list++)
		{
			for (i = 0; i < MAX_CC_NUM; i++)
			{
				if (g_cc_ipaddr_list[i][0] == 0)
					continue;

				if (socketList[list].rpc_fd[i] == 0)
				{
					/*printf("\r=== socketList[%d].rpc_id[%d] = %d\n", list, i, socketList[list].rpc_fd[i]);			*/
					while(1)
					{
						/*printf("\rRecreat the socket....\n");*/
						socketList[list].rpc_fd[i] = socket(AF_INET, SOCK_STREAM, 0);
						if (socketList[list].rpc_fd[i] < 0)
						{
							printf("\r\n func = %s line = %d Create socket failure !\r\n", __FUNCTION__, __LINE__);
							return -1;
						}
						memset(&serv_addr, 0, sizeof(struct sockaddr_in));
						serv_addr.sin_family = AF_INET;
						serv_addr.sin_port = RPC_SERV_PORT;
						serv_addr.sin_addr.s_addr = inet_addr(g_cc_ipaddr_list[i]);
						if(ERROR == connect(socketList[list].rpc_fd[i], (struct sockaddr*)&serv_addr, sizeof(struct sockaddr)))
						{
							printf("\r\n func = %s line = %d Connection failure !\r\n", __FUNCTION__, __LINE__);
							close(socketList[list].rpc_fd[i]);
							socketList[list].rpc_fd[i] = 0;
							taskDelay(100);
						}
						else
						{
							/*printf("\r\n %s, rpc_fd:%d bind Server:%s OK\r\n", __FUNCTION__, socketList[list].rpc_fd[i], g_cc_ipaddr_list[i]);*/
							break ;
						}
					}
					/*printf("<RpcSocketReCreate>socketListIn num = %d\r\n",list);*/
					socketListIn(list);
				}
			}
		}
	}
	
	return 0;
}

void memset_socket_list(int index)
{
	memset(&socketList[index], 0, sizeof(socketList[index]));
}
#ifdef _USE_SEM_
SEM_ID	socket_list_sem_id;
#endif
int socketListSemInit()
{
#ifdef _USE_SEM_
	socket_list_sem_id = semMCreate( SEM_Q_PRIORITY | SEM_INVERSION_SAFE );
    if ((int)socket_list_sem_id == 0)
        printf("\r\n +++++ socket_list_sem_id is 0 +++++ \r\n");
#endif
	return 0;
}
#ifdef _USE_SEM_
static int socket_list_sem_counter = 0;
#endif
void socketListLockTake()
{
#ifdef _USE_SEM_
	if (semTake(socket_list_sem_id, WAIT_FOREVER) == ERROR)
        printf("\r\n ****** socketListLockTake error ****** \r\n");

    if (socket_list_sem_counter++ != 0)
    {
        printf("\r\n ****** <socketListLockTake> socket_list_sem_counter error ****** \r\n");
        while (1)
            taskDelay(10);
    }
#endif
}

void socketListLockGive()
{
#ifdef _USE_SEM_
    if (--socket_list_sem_counter != 0)
    {
        printf("\r\n ****** socketListLockGive socket_list_sem_counter error ****** \r\n");
        while (1)
            taskDelay(10);
    }
	semGive(socket_list_sem_id);
#endif
}

int socketListInit()
{
	memset(socketList,0,sizeof(socketList));
	socketListSemInit();
	RpcSocketCreate();
	return 0;
}
int socketListOut()
{
	int  out=0;

	RpcSocketReCreate();
	socketListLockTake();
	while(out<SOCKET_LIST_NUM)
	{
		if(socketList[out].valid)
		{
			socketList[out].valid = 0;
			break;
		}
		else
		{
			out++;
		}
	}
	if(out>=SOCKET_LIST_NUM)
	{
		socketListLockGive();
		return -1;
	}
	socketListLockGive();
	return out;
}
int socketListIn(int num)
{
	if(num >= SOCKET_LIST_NUM)
	{
		/*printf(" <socketListIn>num = %d\r\n",num);*/
		return -1;
	}
	socketListLockTake();
	/*if((rear+1)%SOCKET_LIST_NUM==front)
	{
		printf("full\r\n");
		return(-1);
	}
	else
	{
		rear=(rear+1)%SOCKET_LIST_NUM;
		return(0);
	}*/
	if(socketList[num].valid==1)
	{
		/*printf("socketList[num].volid=1\r\n");*/
		socketListLockGive();
		return -1;
	}
	else
	{
		socketList[num].valid=1;
		socketListLockGive();	
		return 0;
	}
}
